package com.feng.fengDUtil.dao;

import org.apache.commons.dbutils.DbUtils;

import javax.sql.DataSource;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.SQLException;

public class ConnectionManager
{
    private DataSource dataSource;
    private final boolean isSpringTransaction;
    private final ThreadLocal<Connection> threadLocalConnection = new ThreadLocal();
    private final ThreadLocal<Boolean> inTranction = new ThreadLocal();
    private final int ACTION_CLOSE_ONLY = 1;
    private final int ACTION_COMMIT = 2;
    private final int ACTION_ROLLBACK = 3;

    public ConnectionManager(DataSource dataSource) {
        this.dataSource = dataSource;
        this.isSpringTransaction = false;
    }

    public ConnectionManager(DataSource dataSource,boolean isSpringTransaction) {
        this.dataSource = dataSource;
        this.isSpringTransaction = isSpringTransaction;
    }

    private Connection getConnection()
    {
        try {
            Connection conn = (Connection)this.threadLocalConnection.get();
            return conn; } catch (Exception var1) {
        }
        return null;
    }

    public Connection getConnectionOrNewFromDataSoureIfNull() throws Exception
    {
        if(isSpringTransaction){
            return this.dataSource.getConnection();
        }
        Connection conn = getConnection();
        if (conn == null) {
            try {
                conn = this.dataSource.getConnection();
                conn.setAutoCommit(true);
            } catch (SQLException var3) {
                var3.printStackTrace();
            }
            this.threadLocalConnection.set(conn);
        }
        boolean tranction = isInTranction();
        setAutoCommit(conn, !tranction);
        return conn;
    }

    private void setAutoCommit(Connection conn, boolean commit) {
        try {
            conn.setAutoCommit(commit);
        } catch (SQLException var3) {
            var3.printStackTrace();
        }
    }

    public void closeConnectionByException(boolean hasException)
    {
        if(isSpringTransaction){
            return;
        }
        if (hasException) {
            closeConnection(getConnection(), ACTION_ROLLBACK);
        }
        else if (!isInTranction())
            closeConnection(getConnection(), ACTION_CLOSE_ONLY);
    }

    private boolean isInTranction()
    {
        if(inTranction.get() == null){
            inTranction.set(false);
        }
        return inTranction.get();
    }

    public void beginTranSaction()
    {
        this.inTranction.set(Boolean.valueOf(true));
    }

    private void printMessage(String msg, PrintStream prn) {
        prn.println(msg);
    }

    private void printMessage(String msg) {
        printMessage(msg, System.err);
    }

    public void commitAndCloseConnection() {
        closeConnection(getConnection(), ACTION_COMMIT);
    }

    public void rollbackAndCloseConnection() {
        closeConnection(getConnection(), ACTION_ROLLBACK);
    }

    private void closeConnection(Connection conn, int action) {
        switch (action) {
            case ACTION_COMMIT:
                DbUtils.commitAndCloseQuietly(conn);
                break;
            case ACTION_ROLLBACK:
                DbUtils.rollbackAndCloseQuietly(conn);
                break;
            default:
                DbUtils.closeQuietly(conn);
        }

        this.inTranction.set(Boolean.valueOf(false));
        this.threadLocalConnection.set(null);
    }
}